package com.visionblue.business.ship.page.collection

import com.visionblue.business.ship.model.bean.local.VolumeErrorInfo
import com.visionblue.business.ship.model.repository.FlowVolumeRepository
import java.math.BigDecimal

/**
 * @author: xlh
 * @date: 2020-07-22 8:27 AM
 * @desc:
 */
interface IFlowVolumeErrorParser {

    fun checkWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo?

    fun checkWasteWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo?

    fun checkOil(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo?

    fun checkSonic(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo?

    fun updateOilVolume(positiveAccumulationVal: String)

    fun updateWaterVolume(positiveAccumulationVal: String)

    fun updateWasteWaterVolume(positiveAccumulationVal: String)

    fun updateSonicVolume(positiveAccumulationVal: String)

//    fun clearWater()
//
//    fun clearOil()
}

class InFlowVolumeErrorParserImpl(
    private val flowVolumeRepository: FlowVolumeRepository
) : IFlowVolumeErrorParser {

//    private var volumeCounter: AtomicInteger = AtomicInteger(0)

    override fun checkWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {

        if (positiveAccumulationVal == 0.0) {
            return null
        }


        // 最后一次为空
        val lastWaterDecimal =
            flowVolumeRepository.lastInWaterVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastWaterDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalInWaterErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeWaterVolumeError(
            flowVolumeRepository.totalInWaterErrorVolume,
            pipeName
        )

    }

    override fun checkWasteWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {

        if (positiveAccumulationVal == 0.0) {
            return null
        }


        // 最后一次为空
        val lastWaterDecimal =
            flowVolumeRepository.lastInWasteWaterVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastWaterDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalInWasteWaterErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeWasteWaterVolumeError(
            flowVolumeRepository.totalInWasteWaterErrorVolume,
            pipeName
        )

    }

    override fun checkOil(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {

        if (positiveAccumulationVal == 0.0) {
            return null
        }

        // 最后一次为空
        val lastWaterDecimal =
            flowVolumeRepository.lastInOilVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastWaterDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalInOilErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeOilVolumeError(
            flowVolumeRepository.totalInOilErrorVolume,
            pipeName
        )
    }

    override fun checkSonic(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {
        if (positiveAccumulationVal == 0.0) {
            return null
        }

        // 最后一次为空
        val lastSonicDecimal =
            flowVolumeRepository.lastInSonicVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastSonicDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalInSonicErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeSonicVolumeError(
            flowVolumeRepository.totalInSonicErrorVolume,
            pipeName
        )

    }

    override fun updateSonicVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastInSonicVolume = positiveAccumulationVal
    }

    override fun updateOilVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastInOilVolume = positiveAccumulationVal
    }

    override fun updateWaterVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastInWaterVolume = positiveAccumulationVal
    }

    override fun updateWasteWaterVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastInWasteWaterVolume = positiveAccumulationVal
    }
//    override fun clearWater() {
//        flowVolumeRepository.totalInWaterErrorVolume = 0f
//    }
//
//    override fun clearOil() {
//        flowVolumeRepository.totalInOilErrorVolume = 0f
//    }
}

class OutFlowVolumeErrorParserImpl(private val flowVolumeRepository: FlowVolumeRepository) :
    IFlowVolumeErrorParser {

    override fun checkWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {

        if (positiveAccumulationVal == 0.0) {
            return null
        }


        // 最后一次为空
        val lastWaterDecimal =
            flowVolumeRepository.lastOutWaterVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastWaterDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalOutWaterErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeWaterVolumeError(
            flowVolumeRepository.totalOutWaterErrorVolume,
            pipeName
        )
    }

    override fun checkWasteWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {

        if (positiveAccumulationVal == 0.0) {
            return null
        }


        // 最后一次为空
        val lastWaterDecimal =
            flowVolumeRepository.lastOutWasteWaterVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastWaterDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalOutWasteWaterErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeWasteWaterVolumeError(
            flowVolumeRepository.totalOutWasteWaterErrorVolume,
            pipeName
        )
    }

    override fun checkOil(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {

        if (positiveAccumulationVal == 0.0) {
            return null
        }

        // 最后一次为空
        val lastWaterDecimal =
            flowVolumeRepository.lastOutOilVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastWaterDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalOutOilErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeOilVolumeError(
            flowVolumeRepository.totalOutOilErrorVolume,
            pipeName
        )
    }

    override fun updateOilVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastOutOilVolume = positiveAccumulationVal
    }

    override fun updateWaterVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastOutWaterVolume = positiveAccumulationVal
    }

    override fun updateWasteWaterVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastOutWasteWaterVolume = positiveAccumulationVal
    }

    override fun checkSonic(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {
        if (positiveAccumulationVal == 0.0) {
            return null
        }

        // 最后一次为空
        val lastSonicDecimal =
            flowVolumeRepository.lastOutSonicVolume.toBigDecimalOrNull() ?: return null

        // 计算误差范围
        val delta = lastSonicDecimal.subtract(BigDecimal(positiveAccumulationVal)).abs()

        // 误差允许范围内 discard
        if (delta.toDouble() < ERROR_DELTA) {
            return null
        }

        flowVolumeRepository.totalOutSonicErrorVolume += delta.toFloat()

//        val pipeCount = menuConfigRepository.getMenuItemsByOutput(false)
//            .filter { it.name == WATER_VOLUME_NAME || it.name == OIL_VOLUME_NAME }.size
        return VolumeErrorInfo.makeSonicVolumeError(
            flowVolumeRepository.totalOutSonicErrorVolume,
            pipeName
        )
    }

    override fun updateSonicVolume(positiveAccumulationVal: String) {
        flowVolumeRepository.lastOutSonicVolume = positiveAccumulationVal
    }

    //    override fun clearWater() {
//        flowVolumeRepository.totalOutWaterErrorVolume = 0f
//    }
//
//    override fun clearOil() {
//        flowVolumeRepository.totalOutOilErrorVolume = 0f
//    }
}

//class FakeInVolumeErrorParserImpl : IFlowVolumeErrorParser {
//
//    override fun checkWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {
//        return VolumeErrorInfo.makeWaterVolumeError(1f, pipeName)
//    }
//
//    override fun checkOil(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {
//        return VolumeErrorInfo.makeOilVolumeError(2f, pipeName)
//    }
//
//    override fun updateOilVolume(positiveAccumulationVal: String) {
//
//    }
//
//    override fun updateWaterVolume(positiveAccumulationVal: String) {
//
//    }
//
////    override fun clearWater() {
////
////    }
////
////    override fun clearOil() {
////
////    }
//}
//
//class FakeOutVolumeErrorParserImpl : IFlowVolumeErrorParser {
//
//    override fun checkWater(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {
//        return VolumeErrorInfo.makeWaterVolumeError(1f, pipeName)
//    }
//
//    override fun checkOil(positiveAccumulationVal: Double, pipeName: String?): VolumeErrorInfo? {
//        return VolumeErrorInfo.makeOilVolumeError(2f, pipeName)
//    }
//
//    override fun updateOilVolume(positiveAccumulationVal: String) {
//
//    }
//
//    override fun updateWaterVolume(positiveAccumulationVal: String) {
//
//    }
//
////    override fun clearWater() {
////
////    }
////
////    override fun clearOil() {
////
////    }
//}

private const val ERROR_DELTA = 0.01